package bjut.core.beanPostProcessor;

import bjut.core.extension.ExtensionLoader;
import bjut.core.factory.SingletonFactory;
import bjut.core.annotation.ZRpcReference;
import bjut.core.annotation.ZRpcService;
import bjut.core.config.ProviderConfig;
import bjut.core.interfaces.ServiceProvider;
import bjut.core.interfaces.ZRpcRequestTransport;
import bjut.core.proxy.ZRpcClientProxy;
import bjut.core.zookeeper.ZkServiceProviderImpl;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;

/**
 * @Author: zhuzhiming
 * @Date: 2022/4/6 22:48
 */
@Component
public class ZRpcBeanPostProcessor implements BeanPostProcessor {

    private final ServiceProvider serviceProvider;
    private final ZRpcRequestTransport rpcRequestTransport;

    public ZRpcBeanPostProcessor() {
        serviceProvider = SingletonFactory.getInstance(ZkServiceProviderImpl.class);
        this.rpcRequestTransport = ExtensionLoader.getExtensionLoader(ZRpcRequestTransport.class).getExtension("true");
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

        if (bean.getClass().isAnnotationPresent(ZRpcService.class)) {
            ZRpcService zRpcService = bean.getClass().getAnnotation(ZRpcService.class);
            ProviderConfig providerConfig = ProviderConfig.builder()
                    .group(zRpcService.group())
                    .version(zRpcService.version())
                    .service(bean)
                    .build();

            serviceProvider.registerService(providerConfig);
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

        Field[] fields = bean.getClass().getDeclaredFields();

        for (Field field : fields) {
            ZRpcReference rpcReference = field.getAnnotation(ZRpcReference.class);
            if (rpcReference != null) {
                ProviderConfig providerConfig = ProviderConfig.builder()
                        .group(rpcReference.group())
                        .version(rpcReference.version())
                        .build();
                ZRpcClientProxy clientProxy = new ZRpcClientProxy(rpcRequestTransport, providerConfig);
                Object proxy = clientProxy.getProxy(field.getType());
                field.setAccessible(true);
                try {
                    // 属性修改为代理对象
                    field.set(bean, proxy);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
        return bean;
    }
}
